//----------------------------------------------------------------------------
//  ,-.
// /_\___ ,   CA Framework
// '  ___\    (C) Riccardo Capra - http://riccar.do
//  //   \\
//----------------------------------------------------------------------------
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//----------------------------------------------------------------------------

#ifndef NJ_MEM_UTILS_H
#	define NJ_MEM_UTILS_H

#	include "NjExample01.h"

	/// \brief Helper functions for operations on memory areas
	class NjMemUtils
	{
	public:
		/// \brief Copies a memory block from \em pSour to \em pDest
		///
		/// It is required that uSourSize<=uDestSize.
		/// On some build configurations it will assert if the condition is not respected
		/// \param pDest The start address of the destination memory area
		/// \param uDestSize The maximum size of the destination memory area
		/// \param pSour The start address of the source memory area
		/// \param uSourSize The size of the destination memory area
		static void Copy(void * pDest, NjUint uDestSize, void const * pSour, NjUint uSourSize);

		/// \brief Initializes all the bytes of a memory area to \em uValue
		/// \param pDest The start address of the destination memory area
		/// \param uDestSize The size of the destination memory area
		/// \param uValue The value to be used to inizialize all the bytes of the memory area
		static void Set(void * pDest, NjUint uDestSize, NjUint8 uValue);

		/// \brief Moves a memory block from \em pSour to \em pDest
		///
		/// It is required that uSourSize<=uDestSize.
		/// On some build configurations it will assert if the condition is not respected
		///
		/// This function will copy pSour to pDest even if they are overlapping
		/// \param pDest The start address of the destination memory area
		/// \param uDestSize The maximum size of the destination memory area
		/// \param pSour The start address of the source memory area
		/// \param uSourSize The size of the destination memory area
		static void Move(void * pDest, NjUint uDestSize, void const * pSour, NjUint uSourSize);

		/// \brief Initializes all the bytes of a memory area to 0
		/// \param pDest The start address of the destination memory area
		/// \param uDestSize The size of the destination memory area
		static void Zero(void * pDest, NjUint uDestSize);

		/// \brief Compares the content of two memory areas
		/// \param pLeft The start address of one of the two memory areas
		/// \param pRight The start address of the other memory areas
		/// \param uSize The number of bytes to be compared
		/// \return The function will return 0 if the two memory areas matches, -1 if starting from the beginnin a certain number of bytes matches between the two areas and then the left buffer has a smaller value of the right buffer, 1 otherwise
		static NjInt Compare(void const * pLeft, void const * pRight, NjUint uSize);

	private:
		NJ_DISABLE_INSTANCE(NjMemUtils);
	};

#	include "NjMemUtils_inline.h"

#	if defined(NJ_PLATFORM_WIN32) || defined(NJ_PLATFORM_WIN64)
#		include "NjMemUtilsWin_inline.h"
#	elif defined(NJ_PLATFORM_LINUX_X86) || defined(NJ_PLATFORM_LINUX_X86_64)
#		include "NjMemUtilsLinux_inline.h"
#	else
#		error "Unsupported platform configuration"
#	endif

#endif // NJ_MEM_UTILS_H
